import {
  BadRequestException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { CreateEnterpriseDto } from './dto/create-enterprise.dto';
import { UpdateEnterpriseDto } from './dto/update-enterprise.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Enterprise } from './entities/enterprise.entity';
import { In, Like, Repository } from 'typeorm';
import { EnterpriseBackground } from './entities/enterprise-background.entity';
import { Industry } from './entities/industry.entity';

import { EnterpriseBackgroundData } from './types/EnterpriseBackgroundData';
import { Patent } from './entities/patent.entity';
import { CreatePatentDto } from './dto/create-patent.dto';
import { UpdatePatentDto } from './dto/update-patent.dto';
import { CreateTrademarkDto } from './dto/create-trademark.dto';
import { Trademark } from './entities/trademark.entity';
import { UpdateTrademarkDto } from './dto/update-trademark.dto';
import { CreateExecutiveDto } from './dto/create-executive.dto';
import { Executive } from './entities/executive.entity';
import { UpdateExecutiveDto } from './dto/update-executive.dto';
import { User } from 'src/user/entities/user.entity';
import { Favorite } from './entities/favorite.entity';
import { DailyCommentStats } from 'src/statistic/entities/dailyCommentStats.entity';
import { EnterpriseSearchStats } from 'src/statistic/entities/enterpriseSearchStats.entity';
import { TopKeywords } from 'src/statistic/entities/topKeywords .entity';
import { DailyKeyStats } from 'src/statistic/entities/dailyKeyStats.entity';
import { NotificationGateway } from 'src/notification/notification.gateway';
import { EnterpriseRisk } from './entities/enterprise-risk.entity';

export default interface FavoriteData {
  enterprise: number[];
  patent: number[];
  trademark: number[];
  executive: number[];
}
@Injectable()
export class EnterpriseService {
  constructor(private readonly notificationGateway: NotificationGateway) {}
  @InjectRepository(Enterprise)
  private enterpriseRepository: Repository<Enterprise>;

  @InjectRepository(EnterpriseBackground)
  private enterpriseBackgroundRepository: Repository<EnterpriseBackground>;

  @InjectRepository(Industry)
  private industryRepository: Repository<Industry>;

  @InjectRepository(Patent)
  private patentRepository: Repository<Patent>;

  @InjectRepository(Trademark)
  private trademarkRepository: Repository<Trademark>;

  @InjectRepository(Executive)
  private executiveRepository: Repository<Executive>;

  @InjectRepository(EnterpriseSearchStats)
  private enterpriseSearchStatsRepository: Repository<EnterpriseSearchStats>;
  @InjectRepository(TopKeywords)
  private topKeywordsRepository: Repository<TopKeywords>;
  @InjectRepository(DailyKeyStats)
  private dailyKeyStatsRepository: Repository<DailyKeyStats>;

  @InjectRepository(EnterpriseRisk)
  private enterpriseRiskRepository: Repository<EnterpriseRisk>;

  async initData() {
    const industry1 = new Industry();
    industry1.name = '互联网';

    const industry2 = new Industry();
    industry2.name = '人工智能';
    await this.industryRepository.save([industry1, industry2]);
    // 创建企业信息
    const enterprise1 = this.enterpriseRepository.create({
      name: '腾讯科技',
      registrationNo: '440301103432709',
      legalRepresentative: '马化腾',
      operationStatus: '存续',
      registeredAddress: '广东省深圳市南山区科技园',
      registeredCapital: 10000000,
    });

    const enterprise2 = this.enterpriseRepository.create({
      name: '字节跳动',
      registrationNo: '91110108MA01A6T2XU',
      legalRepresentative: '张一鸣',
      operationStatus: '存续',
      registeredAddress: '北京市海淀区上地创业路6号',
      registeredCapital: 10000000,
    });

    const enterprise3 = this.enterpriseRepository.create({
      name: '阿里巴巴',
      registrationNo: '330000400004748',
      legalRepresentative: '马云',
      operationStatus: '存续',
      registeredAddress: '浙江省杭州市余杭区文一西路969号',
      registeredCapital: 20000000,
    });

    enterprise1.industries = [industry1, industry2];
    enterprise2.industries = [industry1];
    enterprise3.industries = [industry1, industry2];

    // 先保存企业信息
    const savedEnterprises = await this.enterpriseRepository.save([
      enterprise1,
      enterprise2,
      enterprise3,
    ]);

    const [dbEnterprise1, dbEnterprise2, dbEnterprise3] = savedEnterprises;

    // 创建企业背景信息，并关联企业
    const background1 = this.enterpriseBackgroundRepository.create({
      enterprise: dbEnterprise1, // 关联企业
      historicalInfo: '腾讯科技成立于1998年，专注于互联网服务',
      lawsuits: [
        {
          caseNo: '202101',
          reason: '知识产权纠纷',
          date: '2021-06-15',
          result: '败诉',
        },
        {
          caseNo: '202102',
          reason: '合同纠纷',
          date: '2021-07-20',
          result: '和解',
        },
      ],
      administrativePenalties: [
        {
          penaltyNo: '202001',
          reason: '广告违规',
          amount: 500000,
          date: '2020-08-10',
        },
      ],
      dishonestyRecords: [],
      movablePropertyMortgages: [
        {
          mortgageNo: 'M001',
          asset: '部分股权',
          value: '5000万',
          status: '已抵押',
        },
      ],
    });

    const background2 = this.enterpriseBackgroundRepository.create({
      enterprise: dbEnterprise2,
      historicalInfo: '字节跳动成立于2012年，主营短视频与AI技术',
      lawsuits: [
        {
          caseNo: '202201',
          reason: '数据隐私诉讼',
          date: '2022-05-10',
          result: '胜诉',
        },
      ],
      administrativePenalties: [
        {
          penaltyNo: '202101',
          reason: '用户数据存储违规',
          amount: 1000000,
          date: '2021-09-15',
        },
      ],
      dishonestyRecords: [],
      movablePropertyMortgages: [],
    });

    const background3 = this.enterpriseBackgroundRepository.create({
      enterprise: dbEnterprise3,
      historicalInfo: '阿里巴巴成立于1999年，专注于电子商务与云计算',
      lawsuits: [
        {
          caseNo: '202301',
          reason: '反垄断调查',
          date: '2023-04-12',
          result: '和解',
        },
      ],
      administrativePenalties: [
        {
          penaltyNo: '202101',
          reason: '不正当竞争',
          amount: 18000000000,
          date: '2021-03-15',
        },
      ],
      dishonestyRecords: [],
      movablePropertyMortgages: [
        {
          mortgageNo: 'M002',
          asset: '部分资产',
          value: '20亿',
          status: '已抵押',
        },
      ],
    });

    // 保存企业背景信息
    await this.enterpriseBackgroundRepository.save([
      background1,
      background2,
      background3,
    ]);
  }

  // 分页查询企业信息
  async findEnterprisesList(
    name: string,
    registrationNo: string,
    legalRepresentative: string,
    registeredCapital: string,
    registeredAddress: string,
    operationStatus: string,
    pageNo: number,
    pageSize: number,
  ) {
    const skipCount = (pageNo - 1) * pageSize;

    const condition: Record<string, any> = {};

    if (name) {
      condition.name = Like(`%${name}%`);
      // 查询有没有该关键字，有的话，就加1，没有创建该关键字设置为1
      const enterpriseKey = await this.topKeywordsRepository.findOne({
        where: {
          keyword: name,
        },
      });

      if (enterpriseKey) {
        enterpriseKey.searchCount += 1;
        await this.topKeywordsRepository.save(enterpriseKey);
      } else {
        const newEnterpriseKey = new TopKeywords();
        newEnterpriseKey.keyword = name;
        newEnterpriseKey.searchCount = 1;
        await this.topKeywordsRepository.save(newEnterpriseKey);
      }
      const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD 格式
      let dailyStats = await this.dailyKeyStatsRepository.findOne({
        where: { date: today },
      });
      if (dailyStats) {
        // 如果记录存在，则将 keyCount 加 1
        dailyStats.keyCount += 1;
      } else {
        // 如果记录不存在，则创建新的 DailyKeyStats 记录
        dailyStats = new DailyKeyStats();
        dailyStats.date = today;
        dailyStats.keyCount = 1;
      }
      await this.dailyKeyStatsRepository.save(dailyStats);
    }
    if (registrationNo) {
      condition.registrationNo = Like(`%${registrationNo}%`);
    }
    if (legalRepresentative) {
      condition.legalRepresentative = Like(`%${legalRepresentative}%`);
    }
    if (registeredCapital) {
      condition.registeredCapital = Like(`%${registeredCapital}%`);
    }
    if (registeredAddress) {
      condition.registeredAddress = Like(`%${registeredAddress}%`);
    }
    if (operationStatus) {
      condition.operationStatus = Like(`%${operationStatus}%`);
    }

    const [enterprises, totalCount] =
      await this.enterpriseRepository.findAndCount({
        select: [
          'id',
          'name',
          'registrationNo',
          'legalRepresentative',
          'registeredCapital',
          'registeredAddress',
          'operationStatus',
          'establishTime',
          'createTime',
          'updateTime',
        ],
        skip: skipCount,
        take: pageSize,
        where: condition,
      });

    return {
      enterprises,
      totalCount,
    };
  }

  async findEnterprise() {
    return await this.enterpriseRepository.find();
  }

  // 创建企业基本信息
  async create(enterpriseDto: CreateEnterpriseDto) {
    const enterprise = await this.enterpriseRepository.findOneBy({
      name: enterpriseDto.name,
    });

    if (enterprise) {
      throw new BadRequestException('企业已存在');
    }

    const savedEnterprise = await this.enterpriseRepository.save(enterpriseDto);

    // 发送通知
    await this.sendNotificationToUsers(
      savedEnterprise.id,
      `您关注的企业-${savedEnterprise.name}-新增了基本信息，请及时查看`,
    );

    return savedEnterprise;
  }

  // 更新企业基本信息
  async update(enterpriseDto: UpdateEnterpriseDto) {
    const enterprise = await this.enterpriseRepository.findOneBy({
      id: enterpriseDto.id,
    });
    if (!enterprise) {
      throw new BadRequestException('企业不存在!');
    }

    enterprise.name = enterpriseDto.name;
    enterprise.establishTime = enterpriseDto.establishTime;
    enterprise.legalRepresentative = enterpriseDto.legalRepresentative;
    enterprise.operationStatus = enterpriseDto.operationStatus;
    enterprise.registeredAddress = enterpriseDto.registeredAddress;
    enterprise.registeredCapital = enterpriseDto.registeredCapital;
    enterprise.registrationNo = enterpriseDto.registrationNo;

    await this.enterpriseRepository.update(
      {
        id: enterprise.id,
      },
      enterprise,
    );
    // 发送通知
    await this.sendNotificationToUsers(
      enterprise.id,
      `您关注的企业-${enterprise.name}-更新了基本信息，请及时查看`,
    );
    return 'success';
  }

  // 根据 ID 查找企业信息
  async findById(userId: number, enterpriseId: number) {
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: enterpriseId },
    });
    // 将查询到的企业名字存到enterpriseSearchStatsRepository
    let stats = await this.enterpriseSearchStatsRepository.findOne({
      where: { enterprise: { id: enterpriseId } },
      relations: ['enterprise'],
    });
    if (!stats) {
      // 如果没有记录，创建新统计项
      stats = this.enterpriseSearchStatsRepository.create({
        enterprise,
        searchCount: 1,
      });
    } else {
      // 如果已有记录，增加搜索次数
      stats.searchCount += 1;
    }
    await this.enterpriseSearchStatsRepository.save(stats);
    console.log('11111');

    if (!enterprise) {
      throw new NotFoundException('企业信息不存在');
    }
    const favorite = await this.favoriteRepository.findOne({
      where: { user: { id: userId }, enterprise: { id: enterpriseId } },
    });

    return {
      ...enterprise,
      isFavorite: !!favorite,
    };
  }

  // 删除企业信息
  async delete(id: number) {
    const enterprise = await this.enterpriseRepository.findOneBy({
      id,
    });
    await this.enterpriseRepository.delete(id);
    // 发送通知给关注该企业的用户
    await this.sendNotificationToUsers(
      id,
      `您关注的企业-${enterprise.name}-删除了基本信息，请及时查看`,
    );
    return 'success';
  }

  // 获取企业背景
  async getEnterpriseBackgroundById(enterpriseId: number) {
    const background = await this.enterpriseBackgroundRepository.findOne({
      where: { enterprise: { id: enterpriseId } },
    });

    if (!background) {
      throw new BadRequestException('企业背景不存在');
    }

    return background;
  }

  async getEnterpriseBackgroundList(
    name: string,
    pageNo: number,
    pageSize: number,
  ) {
    const skip = (pageNo - 1) * pageSize;

    // 构造查询条件
    const whereCondition: any = {};
    if (name) {
      const enterprises = await this.enterpriseRepository.find({
        where: { name: Like(`%${name}%`) },
      });
      if (enterprises.length > 0) {
        // 使用 id 数组进行条件过滤
        whereCondition['enterprise.id'] = In(enterprises.map((e) => e.id));
      }
    }

    const [backgrounds, total] =
      await this.enterpriseBackgroundRepository.findAndCount({
        where: whereCondition,
        relations: ['enterprise'],
        skip,
        take: pageSize,
        order: { createTime: 'DESC' },
      });

    return {
      list: backgrounds,
      total,
      pageNo,
      pageSize,
    };
  }

  // 获取行业排行榜
  async getIndustryRankings(industryId: number) {
    // 查询行业信息
    const industry = await this.industryRepository.findOne({
      where: { id: industryId },
    });

    if (!industry) {
      throw new BadRequestException('行业不存在');
    }

    // 获取该行业内的所有企业，并根据 `registeredCapital` 进行降序排序
    const enterprises = await this.enterpriseRepository
      .createQueryBuilder('enterprise')
      .innerJoin(
        'enterprise.industries',
        'industry',
        'industry.id = :industryId',
        { industryId },
      )
      .orderBy('enterprise.registeredCapital', 'DESC')
      .select([
        'enterprise.id',
        'enterprise.name',
        'enterprise.registeredCapital',
        'enterprise.registrationNo',
        'enterprise.legalRepresentative',
        'enterprise.registeredAddress',
        'enterprise.operationStatus',
      ])
      .getMany();

    if (!enterprises.length) {
      throw new BadRequestException('该行业没有企业数据');
    }

    // 生成排名
    const rankings = enterprises.map((enterprise, index) => ({
      rank: index + 1, // 排名从 1 开始
      enterprise,
    }));

    return {
      industry,
      rankings,
    };
  }

  // 获取所有行业的企业排名
  async getAllIndustriesRankings() {
    // 查询所有行业
    const industries = await this.industryRepository.find();
    const allRankings = [];

    for (const industry of industries) {
      // 查询该行业内的所有企业，并按 `registeredCapital` 降序排序
      const enterprises = await this.enterpriseRepository
        .createQueryBuilder('enterprise')
        .innerJoin(
          'enterprise.industries',
          'industry',
          'industry.id = :industryId',
          { industryId: industry.id },
        )
        .orderBy('enterprise.registeredCapital', 'DESC')
        .select([
          'enterprise.id',
          'enterprise.name',
          'enterprise.registeredCapital',
          'enterprise.registrationNo',
          'enterprise.legalRepresentative',
          'enterprise.registeredAddress',
          'enterprise.operationStatus',
        ])
        .getMany();

      // 如果该行业没有企业数据，跳过
      if (!enterprises.length) continue;

      // 计算排名
      const rankings = enterprises.map((enterprise, index) => ({
        rank: index + 1, // 排名从 1 开始
        enterprise,
      }));

      allRankings.push({
        industry,
        rankings,
      });
    }

    return { industriesRankings: allRankings };
  }

  // 创建企业背景信息
  async createBackground(data: EnterpriseBackgroundData) {
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: data.enterprise_id },
    });

    if (!enterprise) {
      throw new BadRequestException('企业不存在');
    }
    const enterpriseBack = await this.enterpriseBackgroundRepository.findOne({
      where: {
        enterprise: { id: data.enterprise_id },
      },
      relations: ['enterprise'],
    });
    if (enterpriseBack) {
      throw new BadRequestException('企业的背景信息已存在');
    }

    const validateUniqueIds = (
      array: {
        caseNo?: string;
        penaltyNo?: string;
        recordNo?: string;
        mortgageNo?: string;
      }[],
      type: string,
    ) => {
      const seen = new Set();
      for (const item of array) {
        let id: string;
        switch (type) {
          case 'lawsuits':
            id = item.caseNo;
            break;
          case 'administrativePenalties':
            id = item.penaltyNo;
            break;
          case 'dishonestyRecords':
            id = item.recordNo;
            break;
          case 'movablePropertyMortgages':
            id = item.mortgageNo;
            break;
          default:
            throw new BadRequestException('Invalid type');
        }

        if (seen.has(id)) {
          throw new BadRequestException(`${type} 中编号 ${id} 重复`);
        }
        seen.add(id);
      }
    };

    // 验证每个数组的编号唯一性
    if (data.lawsuits) validateUniqueIds(data.lawsuits, 'lawsuits');
    if (data.administrativePenalties)
      validateUniqueIds(
        data.administrativePenalties,
        'administrativePenalties',
      );
    if (data.dishonestyRecords)
      validateUniqueIds(data.dishonestyRecords, 'dishonestyRecords');
    if (data.movablePropertyMortgages)
      validateUniqueIds(
        data.movablePropertyMortgages,
        'movablePropertyMortgages',
      );

    const background = this.enterpriseBackgroundRepository.create({
      enterprise,
      historicalInfo: data.historicalInfo,
      lawsuits: data.lawsuits || [],
      administrativePenalties: data.administrativePenalties || [],
      dishonestyRecords: data.dishonestyRecords || [],
      movablePropertyMortgages: data.movablePropertyMortgages || [],
    });
    // 保存企业背景信息
    const savedBackground =
      await this.enterpriseBackgroundRepository.save(background);

    await this.calculateRiskScoreByEnterpriseId(enterprise.id);

    const enterpriseRisk = await this.enterpriseRiskRepository.findOne({
      where: { enterpriseId: enterprise.id },
    });

    await this.sendNotificationToUsers(
      background.enterprise.id,
      `您关注的企业-${background.enterprise.name}-更新了背景信息,且企业风险等级已更新为：${enterpriseRisk.riskLevel}，请及时查看`,
    );

    console.log(enterpriseRisk.riskLevel);

    return savedBackground;
  }

  // 更新企业背景信息
  async updateBackground(id: number, data: EnterpriseBackgroundData) {
    const background = await this.enterpriseBackgroundRepository.findOne({
      where: { id },
      relations: ['enterprise'],
    });

    if (!background) {
      throw new BadRequestException('企业背景信息不存在');
    }

    background.historicalInfo =
      data.historicalInfo || background.historicalInfo;

    background.lawsuits = data.lawsuits ?? [];
    background.administrativePenalties = data.administrativePenalties ?? [];
    background.dishonestyRecords = data.dishonestyRecords ?? [];
    background.movablePropertyMortgages = data.movablePropertyMortgages ?? [];
    // 保存更新后的企业背景信息
    const updatedBackground =
      await this.enterpriseBackgroundRepository.save(background);

    const newRiskLevel = await this.calculateRiskScoreByEnterpriseId(
      background.enterprise.id,
    );
    const enterpriseRisk = await this.enterpriseRiskRepository.findOne({
      where: { enterpriseId: background.enterprise.id },
    });
    await this.sendNotificationToUsers(
      background.enterprise.id,
      `您关注的企业-${background.enterprise.name}-更新了背景信息,且企业风险等级已更新为：${newRiskLevel.riskLevel}，请及时查看`,
    );
    return updatedBackground;
  }

  // 删除
  async deleteBackground(id: number) {
    const background = await this.enterpriseBackgroundRepository.findOne({
      where: {
        id,
      },
    });
    if (!background) {
      throw new BadRequestException('企业背景信息不存在');
    }

    // 查询收藏该企业的所有用户
    await this.sendNotificationToUsers(
      background.enterprise.id,
      `您关注的企业-${background.enterprise.name}-删除了背景信息，请及时查看`,
    );

    // 删除企业背景信息
    return this.enterpriseBackgroundRepository.remove(background);
  }

  // 创建行业
  async createIndustry(name: string, description?: string) {
    // 先查看是否存在
    const industry = await this.industryRepository.findOne({
      where: {
        name,
      },
    });
    if (industry) {
      throw new BadRequestException('行业已存在');
    }
    if (!name) {
      throw new BadRequestException('行业名称不能为空');
    }
    return this.industryRepository.save({
      name,
      description,
    });
  }

  // 更新行业
  async updateIndustry(id: number, name: string, description?: string) {
    const industry = await this.industryRepository.findOne({
      where: { id },
    });
    if (!industry) {
      throw new BadRequestException('行业没找到');
    }
    industry.name = name;
    if (description) {
      industry.description = description;
    }

    return this.industryRepository.save(industry);
  }

  // 获取所有行业
  async getAllIndustries(name: string, pageNo: number, pageSize: number) {
    const skipCount = (pageNo - 1) * pageSize;

    // 条件对象
    const condition: Record<string, any> = {};

    if (name) {
      condition.name = Like(`%${name}%`); // 模糊查询行业名称
      // 查询有没有该关键字，有的话，就加1，没有创建该关键字设置为1
      const industriesKey = await this.topKeywordsRepository.findOne({
        where: {
          keyword: name,
        },
      });
      if (industriesKey) {
        industriesKey.searchCount += 1;
        await this.topKeywordsRepository.save(industriesKey);
      } else {
        const newIndustriesKey = new TopKeywords();
        newIndustriesKey.keyword = name;
        newIndustriesKey.searchCount = 1;
        await this.topKeywordsRepository.save(newIndustriesKey);
      }
    }

    const [industries, totalCount] = await this.industryRepository.findAndCount(
      {
        select: ['id', 'name', 'description', 'enterprises'],
        relations: { enterprises: true },
        skip: skipCount,
        take: pageSize,
        where: condition,
      },
    );

    return {
      industries,
      totalCount,
    };
  }

  // 不需要分页，直接获取所有行业
  async getIndustries() {
    const industries = await this.industryRepository.find({
      select: ['id', 'name', 'description'],
    });

    return {
      industries,
    };
  }

  // 删除行业
  async deleteIndustry(id: number) {
    const industry = await this.industryRepository.findOne({
      where: { id },
    });
    if (!industry) {
      throw new BadRequestException('行业没找到');
    }

    return this.industryRepository.remove(industry);
  }

  // 添加企业到行业
  async addEnterpriseToIndustry(enterpriseId: number, industryId: number) {
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: enterpriseId },
      relations: ['industries'],
    });
    if (!enterprise) {
      throw new BadRequestException('企业不存在');
    }

    const industry = await this.industryRepository.findOne({
      where: { id: industryId },
      relations: ['enterprises'],
    });
    if (!industry) {
      throw new BadRequestException('行业不存在');
    }

    if (!enterprise.industries.some((item) => item.id === industryId)) {
      enterprise.industries.push(industry);
      await this.enterpriseRepository.save(enterprise);
    }
    return enterprise;
  }

  // 删除行业的企业
  async removeEnterpriseFromIndustry(enterpriseId: number, industryId: number) {
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: enterpriseId },
      relations: ['industries'],
    });
    console.log(typeof enterpriseId, typeof industryId);

    if (!enterprise) {
      throw new BadRequestException('企业不存在');
    }

    console.log('删除前', enterprise);
    const industry = await this.industryRepository.findOne({
      where: { id: industryId },
    });

    if (!industry) {
      throw new BadRequestException('行业不存在');
    }

    enterprise.industries = enterprise.industries.filter(
      (ind) => ind.id !== +industryId,
    );
    console.log('删除后', enterprise);

    await this.enterpriseRepository.save(enterprise);
    return '企业已从该行业移除';
  }

  async sendNotificationToUsers(enterpriseId: number, message: string) {
    // 从 favorite 表根据企业 id 获取哪些用户收藏了该企业，将所有用户 id 提取到一个数组中
    const userIds = await this.favoriteRepository
      .createQueryBuilder('favorite')
      .select('favorite.userId', 'userId')
      .where('favorite.enterpriseId = :enterpriseId', { enterpriseId })
      .getRawMany();

    const userIdArray = userIds.map((item) => item.userId);

    if (userIdArray.length > 0) {
      await this.notificationGateway.sendToAllClients(message, userIdArray);
    }
  }

  // 添加专利
  async addPatent(createPatentDto: CreatePatentDto) {
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: createPatentDto.enterpriseId },
    });
    if (!enterprise) {
      throw new BadRequestException('企业不存在');
    }
    // 发送通知
    await this.sendNotificationToUsers(
      createPatentDto.enterpriseId,
      `您关注的企业-${enterprise.name}-有新的专利信息被收录了，请及时查看`,
    );

    const patent = new Patent();
    patent.enterprise = enterprise;
    patent.abstract = createPatentDto.abstract;
    patent.applicant = createPatentDto.applicant;
    patent.patentType = createPatentDto.patentType;
    patent.applicationDate = createPatentDto.applicationDate;
    patent.name = createPatentDto.name;
    patent.abstract = createPatentDto.abstract;
    patent.registrationDate = createPatentDto.registrationDate;

    return this.patentRepository.save(patent);
  }

  // 删除专利
  async deletePatent(id: number) {
    // 1. 查询专利信息，获取企业 ID
    const patent = await this.patentRepository.findOne({
      where: { id },
      relations: ['enterprise'], // 关联企业信息
    });

    if (!patent) {
      throw new BadRequestException('专利不存在');
    }

    // 发送通知
    await this.sendNotificationToUsers(
      patent.enterprise.id,
      `您关注的企业-${patent.enterprise.name}-有专利被下架了，请及时查看`,
    );
    // 4. 删除专利
    return this.patentRepository.remove(patent);
  }

  // 更新专利
  async updatePatent(updatePatentDto: UpdatePatentDto) {
    // 1. 查询要更新的专利信息
    const patent = await this.patentRepository.findOne({
      where: { id: updatePatentDto.id },
      relations: ['enterprise'], // 关联企业信息
    });

    if (!patent) {
      throw new BadRequestException('专利不存在');
    }

    // 2. 更新专利数据
    Object.assign(patent, updatePatentDto);

    // 发送通知
    await this.sendNotificationToUsers(
      patent.enterprise.id,
      `您关注的企业-${patent.enterprise.name}-有新的专利信息被更新了，请及时查看`,
    );

    // 5. 保存更新后的专利
    return this.patentRepository.save(patent);
  }

  // 根据id查找专利信息
  async findPatent(id: number) {
    return await this.patentRepository.findOne({
      where: { id },
    });
  }

  // 根据名字查询专利信息
  async findPatentsByName(pageNo: number, pageSize: number, name: string) {
    const skipCount = (pageNo - 1) * pageSize;
    const condition: Record<string, any> = {};
    if (name) {
      condition.name = Like(`%${name}%`);
      // 查询有没有该关键字，有的话，就加1，没有创建该关键字设置为1
      const patentsKey = await this.topKeywordsRepository.findOne({
        where: {
          keyword: name,
        },
      });
      if (patentsKey) {
        patentsKey.searchCount += 1;
        await this.topKeywordsRepository.save(patentsKey);
      } else {
        const newPatentsKey = new TopKeywords();
        newPatentsKey.keyword = name;
        newPatentsKey.searchCount = 1;
        await this.topKeywordsRepository.save(newPatentsKey);
      }
    }
    const [patents, totalCount] = await this.patentRepository.findAndCount({
      where: condition,
      skip: skipCount,
      take: pageSize,
      relations: ['enterprise'], // 如需要关联企业信息
    });
    return {
      patents,
      totalCount,
    };
  }

  // 根据企业id查询专利信息
  async findPatensById(enterpriseId: number, pageNo: number, pageSize: number) {
    const skipCount = (pageNo - 1) * pageSize;

    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: enterpriseId },
    });
    const [patents, totalCount] = await this.patentRepository.findAndCount({
      where: { enterprise: { id: enterpriseId } },
      skip: skipCount,
      take: pageSize,
    });
    return {
      patents,
      enterprise,
      totalCount,
    };
  }

  // 创建商标
  async createTrademark(createTrademarkDto: CreateTrademarkDto) {
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: createTrademarkDto.enterpriseId },
    });
    if (!enterprise) {
      throw new BadRequestException('企业不存在');
    }

    const trademark = new Trademark();
    trademark.name = createTrademarkDto.name;
    trademark.registrationDate = createTrademarkDto.registrationDate;
    trademark.applicant = createTrademarkDto.applicant;
    trademark.applicationDate = createTrademarkDto.applicationDate;
    trademark.enterprise = enterprise;
    // 保存商标并获取商标 ID
    const savedTrademark = await this.trademarkRepository.save(trademark);

    // 发送通知
    await this.sendNotificationToUsers(
      createTrademarkDto.enterpriseId,
      `您关注的企业-${trademark.enterprise.name}-有新的商标信息，请及时查看`,
    );

    return savedTrademark;
  }

  // 删除商标
  async deleteTrademark(id: number) {
    const trademark = await this.trademarkRepository.findOne({
      where: { id },
      relations: ['enterprise'], // 确保加载 enterprise 关系
    });

    if (!trademark) {
      throw new BadRequestException('商标不存在');
    }

    // 确保 trademark.enterprise 存在
    if (!trademark.enterprise) {
      throw new BadRequestException('商标关联的企业不存在');
    }

    // 发送通知
    await this.sendNotificationToUsers(
      trademark.enterprise.id,
      `您关注的企业-${trademark.enterprise.name}删除了一个商标，请及时查看`,
    );

    // 删除商标
    return this.trademarkRepository.remove(trademark);
  }

  // 更新商标
  async updateTrademark(updateTrademarkDto: UpdateTrademarkDto) {
    const trademark = await this.trademarkRepository.findOne({
      where: { id: updateTrademarkDto.id },
    });
    if (!trademark) {
      throw new BadRequestException('商标不存在');
    }
    Object.assign(trademark, updateTrademarkDto);
    // 保存更新后的商标
    const updatedTrademark = await this.trademarkRepository.save(trademark);

    // 发送通知
    await this.sendNotificationToUsers(
      trademark.enterprise.id,
      `您关注的企业-${trademark.enterprise.name}-更新了商标信息，请及时查看`,
    );

    return updatedTrademark;
  }

  // 根据id查找商标信息
  async findTrademarks(id: number) {
    return await this.trademarkRepository.findOne({
      where: { id },
    });
  }
  // 查找商标，通过名称模糊查询
  async findTrademarksByName(pageNo: number, pageSize: number, name: string) {
    const skipCount = (pageNo - 1) * pageSize;
    const condition: Record<string, any> = {};
    if (name) {
      condition.name = Like(`%${name}%`);
      // 查询有没有该关键字，有的话，就加1，没有创建该关键字设置为1
      const trademarkKey = await this.topKeywordsRepository.findOne({
        where: {
          keyword: name,
        },
      });
      if (trademarkKey) {
        trademarkKey.searchCount += 1;
        await this.topKeywordsRepository.save(trademarkKey);
      } else {
        const newTrademarkKey = new TopKeywords();
        newTrademarkKey.keyword = name;
        newTrademarkKey.searchCount = 1;
        await this.topKeywordsRepository.save(newTrademarkKey);
      }
    }
    const [trademark, totalCount] = await this.trademarkRepository.findAndCount(
      {
        where: condition,
        skip: skipCount,
        take: pageSize,
        relations: ['enterprise'], // 如需要关联企业信息
      },
    );

    return {
      trademark,
      totalCount,
    };
  }

  // 根据企业id查询商标信息
  async findTrademarksById(
    enterpriseId: number,
    pageNo: number,
    pageSize: number,
  ) {
    const skipCount = (pageNo - 1) * pageSize;
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: enterpriseId },
    });

    const [trademark, totalCount] = await this.trademarkRepository.findAndCount(
      {
        where: { enterprise: { id: enterpriseId } },
        skip: skipCount,
        take: pageSize,
      },
    );
    return {
      trademark,
      enterprise,
      totalCount,
    };
  }

  // 添加高管
  async addExecutive(createExecutiveDto: CreateExecutiveDto) {
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: createExecutiveDto.enterpriseId },
    });
    if (!enterprise) {
      throw new BadRequestException('企业不存在');
    }

    const executive = new Executive();
    executive.enterprise = enterprise;
    executive.name = createExecutiveDto.name;
    executive.position = createExecutiveDto.position;
    executive.education = createExecutiveDto.education;
    if (createExecutiveDto.photo) executive.photo = createExecutiveDto.photo;
    const savedExecutive = await this.executiveRepository.save(executive);

    // 发送通知
    await this.sendNotificationToUsers(
      createExecutiveDto.enterpriseId,
      `您关注的企业-${executive.enterprise.name}-新增了高管信息，请及时查看`,
    );

    return savedExecutive;
  }

  // 删除高管信息
  async deleteExecutive(id: number) {
    const executive = await this.executiveRepository.findOne({
      where: { id },
      relations: ['enterprise'], // 确保加载 enterprise 关系
    });
    if (!executive) {
      throw new BadRequestException('高管不存在');
    }

    // 发送通知
    await this.sendNotificationToUsers(
      executive.enterprise.id,
      `您关注的企业-${executive.enterprise.name}-删除了一个高管信息，请及时查看`,
    );

    // 删除高管信息
    return this.executiveRepository.remove(executive);
  }

  // 更新高管信息
  async updateExecutive(updateExecutiveDto: UpdateExecutiveDto) {
    const executive = await this.executiveRepository.findOne({
      where: { id: updateExecutiveDto.id },
      relations: ['enterprise'], // 确保加载 enterprise 关系
    });
    if (!executive) {
      throw new BadRequestException('高管不存在');
    }

    Object.assign(executive, updateExecutiveDto);

    // 保存更新后的高管信息
    const updatedExecutive = await this.executiveRepository.save(executive);

    // 发送通知
    await this.sendNotificationToUsers(
      executive.enterprise.id,
      `您关注的企业-${executive.enterprise.name}-更新了高管信息，请及时查看`,
    );

    return updatedExecutive;
  }

  // 根据高管id查询高管信息
  async findExecutive(id: number) {
    return this.executiveRepository.findOne({
      where: { id },
    });
  }

  // 根据名字查询高管信息
  async findExecutivesByName(pageNo: number, pageSize: number, name: string) {
    const skipCount = (pageNo - 1) * pageSize;
    const condition: Record<string, any> = {};
    if (name) {
      condition.name = Like(`%${name}%`);
      // 查询有没有该关键字，有的话，就加1，没有创建该关键字设置为1
      const executiveKey = await this.topKeywordsRepository.findOne({
        where: {
          keyword: name,
        },
      });
      if (executiveKey) {
        executiveKey.searchCount += 1;
        await this.topKeywordsRepository.save(executiveKey);
      } else {
        const newExecutiveKey = new TopKeywords();
        newExecutiveKey.keyword = name;
        newExecutiveKey.searchCount = 1;
        await this.topKeywordsRepository.save(newExecutiveKey);
      }
    }
    const [executive, totalCount] = await this.executiveRepository.findAndCount(
      {
        where: condition,
        skip: skipCount,
        take: pageSize,
        relations: ['enterprise'], // 如需要关联企业信息
      },
    );
    return {
      executive,
      totalCount,
    };
  }

  // 根据企业id查询高管信息
  async findExecutivesById(
    enterpriseId: number,
    pageNo: number,
    pageSize: number,
  ) {
    const skipCount = (pageNo - 1) * pageSize;
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: enterpriseId },
    });

    const [executive, totalCount] = await this.executiveRepository.findAndCount(
      {
        where: { enterprise: { id: enterpriseId } },
        skip: skipCount,
        take: pageSize,
      },
    );
    return {
      executive,
      enterprise,
      totalCount,
    };
  }

  private readonly maxScore = 100;
  private readonly thresholds = {
    legalLawsuits: 2, // 超过 3 个法律诉讼开始扣分
    administrativePenalties: 2, // 超过 2 个行政处罚开始扣分
    dishonestRecords: 1, // 超过 1 个失信记录开始扣分
    movablePropertyMortgages: 1, // 超过 1 个动产抵押开始扣分
  };
  private readonly deduction = 10; // 每超过阈值扣 10 分
  // 企业风险评估
  async calculateRiskScoreByEnterpriseId(enterpriseId: number) {
    const enterpriseBackground =
      await this.enterpriseBackgroundRepository.findOne({
        where: { enterprise: { id: enterpriseId } },
      });
    const enterpriseRisk = await this.enterpriseRiskRepository.findOne({
      where: { enterpriseId },
    });

    if (!enterpriseBackground) {
      throw new BadRequestException('企业背景信息不存在');
    }
    let totalScore = this.maxScore;
    // 法律诉讼扣分
    if (
      enterpriseBackground.lawsuits &&
      enterpriseBackground.lawsuits.length > this.thresholds.legalLawsuits
    ) {
      totalScore -=
        (enterpriseBackground.lawsuits.length - this.thresholds.legalLawsuits) *
        this.deduction;
    }
    // 行政处罚扣分
    if (
      enterpriseBackground.administrativePenalties &&
      enterpriseBackground.administrativePenalties.length >
        this.thresholds.administrativePenalties
    ) {
      totalScore -=
        (enterpriseBackground.administrativePenalties.length -
          this.thresholds.administrativePenalties) *
        this.deduction;
    }

    // 失信记录扣分
    if (
      enterpriseBackground.dishonestyRecords &&
      enterpriseBackground.dishonestyRecords.length >
        this.thresholds.dishonestRecords
    ) {
      totalScore -=
        (enterpriseBackground.dishonestyRecords.length -
          this.thresholds.dishonestRecords) *
        this.deduction;
    }

    // 动产抵押扣分
    if (
      enterpriseBackground.movablePropertyMortgages &&
      enterpriseBackground.movablePropertyMortgages.length >
        this.thresholds.movablePropertyMortgages
    ) {
      totalScore -=
        (enterpriseBackground.movablePropertyMortgages.length -
          this.thresholds.movablePropertyMortgages) *
        this.deduction;
    }
    // 确保总分不小于 0
    if (totalScore < 0) totalScore = 0;

    // 根据得分计算风险等级
    const riskLevel = this.getRiskLevel(totalScore);
    if (enterpriseRisk) {
      enterpriseRisk.totalScore = totalScore;
      enterpriseRisk.riskLevel = riskLevel;
      enterpriseRisk.administrativePenalties =
        enterpriseBackground.administrativePenalties.length;
      enterpriseRisk.dishonestRecords =
        enterpriseBackground.dishonestyRecords.length;
      enterpriseRisk.movablePropertyMortgages =
        enterpriseBackground.movablePropertyMortgages.length;
      enterpriseRisk.legalLawsuits = enterpriseBackground.lawsuits.length;
      await this.enterpriseRiskRepository.save(enterpriseRisk);
    } else {
      const enterpriseRisk = new EnterpriseRisk();
      enterpriseRisk.enterpriseId = enterpriseId;
      enterpriseRisk.totalScore = totalScore;
      enterpriseRisk.riskLevel = riskLevel;
      enterpriseRisk.administrativePenalties =
        enterpriseBackground.administrativePenalties.length;
      enterpriseRisk.dishonestRecords =
        enterpriseBackground.dishonestyRecords.length;
      enterpriseRisk.movablePropertyMortgages =
        enterpriseBackground.movablePropertyMortgages.length;
      enterpriseRisk.legalLawsuits = enterpriseBackground.lawsuits.length;
      await this.enterpriseRiskRepository.save(enterpriseRisk);
    }

    return { score: totalScore, riskLevel };
  }
  // 根据得分返回风险等级
  private getRiskLevel(score: number): string {
    if (score >= 80) {
      return '低风险';
    } else if (score >= 60) {
      return '中低风险';
    } else if (score >= 40) {
      return '中风险';
    } else if (score >= 20) {
      return '中高风险';
    } else {
      return '高风险';
    }
  }

  @InjectRepository(User)
  private userRepository: Repository<User>;
  @InjectRepository(Favorite)
  private favoriteRepository: Repository<Favorite>;

  // 添加收藏
  async addFavorite(userId: number, enterpriseId: number) {
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new BadRequestException('用户不存在');
    }
    const enterprise = await this.enterpriseRepository.findOne({
      where: { id: enterpriseId },
    });
    if (!enterprise) {
      throw new BadRequestException('企业不存在');
    }

    // 检查用户是否已经收藏过该企业
    const existingFavorite = await this.favoriteRepository.findOne({
      where: {
        user: { id: userId },
        enterprise: { id: enterpriseId },
      },
    });
    if (existingFavorite) {
      throw new BadRequestException('企业已收藏');
    }

    const favorite = this.favoriteRepository.create({ user, enterprise });
    return await this.favoriteRepository.save(favorite);
  }

  // 取消收藏
  async removeFavorite(userId: number, enterpriseId: number) {
    const favorite = await this.favoriteRepository.findOne({
      where: {
        user: { id: userId },
        enterprise: { id: enterpriseId },
      },
    });
    if (!favorite) {
      throw new NotFoundException('未找到收藏记录');
    }
    await this.favoriteRepository.remove(favorite);
  }

  // 获取收藏列表
  async getFavorites(userId: number) {
    const favorites = await this.favoriteRepository.find({
      where: {
        user: { id: userId },
      },
      relations: ['enterprise'],
      order: { createTime: 'DESC' },
    });
    return favorites.map((favorite) => ({
      id: favorite.id,
      enterpriseId: favorite.enterprise.id,
      name: favorite.enterprise.name,
      registeredCapital: favorite.enterprise.registeredCapital,
      legalRepresentative: favorite.enterprise.legalRepresentative,
      registeredAddress: favorite.enterprise.registeredAddress,
      createTime: favorite.createTime,
      registrationNo: favorite.enterprise.registrationNo,
    }));
  }
}
